package com.appspot.abcensys.client;

import java.util.List;
import java.util.logging.Logger;

import com.appspot.abcensys.shared.FntRoosterInfo;
import com.appspot.abcensys.shared.Gebruiker;
import com.appspot.abcensys.shared.MenuFactory;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;

/**
 * Classe die gebruikt word wanneer de software net gedeployed is op de App
 * Egine of nieuw project
 * 
 * @author Hugo Zonderland
 * 
 */
public class Installatie {

	// FlexTable
	private FlexTable flxTableHeader, flxTable;

	// Row
	private int row;

	// AbcensysService
	private AbcensysServiceAsync service = (AbcensysServiceAsync) GWT.create(AbcensysService.class);

	// Logger
	private static final Logger log = Logger.getLogger(Installatie.class.getName());

	// Listbox
	private ListBox lstFaculteit, lstOpleiding, lstKlascode;

	// FntRoosterInfo
	private FntRoosterInfo fri = new FntRoosterInfo();

	/**
	 * Constructor
	 */
	public Installatie() {

		Abcensys.setLoadingImage(true);

		// row init
		row = 0;

		// Headertable aanmaken
		flxTableHeader = new FlexTable();
		flxTableHeader.setCellPadding(0);
		flxTableHeader.setCellSpacing(3);
		flxTableHeader.setWidth("900px");
		flxTableHeader.setStyleName("datatable");

		// Link Widget
		HTML linkWidget = new HTML("Je bent nu hier: Abcensys &raquo; Installatie");
		linkWidget.setStyleName("lblLink");
		flxTableHeader.setWidget(row, 0, linkWidget);
		row++;

		// Image
		Image imgInstallatie = new Image();
		imgInstallatie.setAltText("Dashboard");
		imgInstallatie.setUrl("style/icon/map.png");

		// Pagina header
		HTML h1 = new HTML("<h1> " + imgInstallatie.toString() + " Installatie</h1>");
		flxTableHeader.setWidget(row, 0, h1);
		row++;

		Label lblUitlegWelkom = new Label("Welkom bij Abcensys!");
		flxTableHeader.setWidget(row, 0, lblUitlegWelkom);
		row++;

		Label lblUitleg = new Label("Op deze pagina word de eerste gebruikers account aangemaakt. Deze account zal de mogelijkheid hebben Abcensys te beheren.");
		flxTableHeader.setWidget(row, 0, lblUitleg);

		// Datatable aanmaken
		flxTable = new FlexTable();
		flxTable.setCellPadding(0);
		flxTable.setCellSpacing(3);
		flxTable.setWidth("900px");
		flxTable.setStyleName("datatable");

		// Nog een extra controle om er zeker van te zijn dat het systeem
		// geinstalleerd moet worden
		service.installatieModus(new AsyncCallback<Boolean>() {
			public void onFailure(Throwable caught) {
				Window.alert("Er ging iets fout tijdens het ophalen van de gegevens. Probeer het later nog een keer.");
				log.info("Service failure -> installatieModus -> " + caught.getMessage());
			}

			public void onSuccess(Boolean result) {
				if (result) {
					// Doorgaan met installatie
					installSoftware();
				} else {
					Window.alert("Het systeem is reeds geconfigureerd.");
					new Dashboard();
				}
			}
		});
	}

	/**
	 * Hier word de eerste Administrator account aangemaakt en opgeslage
	 */
	private void installSoftware() {

		// Email
		Label lblEmail = new Label("Email adres");
		final TextBox txtEmail = new TextBox();
		flxTable.setWidget(row, 0, lblEmail);
		flxTable.setWidget(row, 1, txtEmail);
		row++;

		// Voornaam
		Label lblVoornaam = new Label("Voornaam");
		final TextBox txtVoornaam = new TextBox();
		flxTable.setWidget(row, 0, lblVoornaam);
		flxTable.setWidget(row, 1, txtVoornaam);
		row++;

		// Achternaam
		Label lblAchternaam = new Label("Achternaam");
		final TextBox txtAchternaam = new TextBox();
		flxTable.setWidget(row, 0, lblAchternaam);
		flxTable.setWidget(row, 1, txtAchternaam);
		row++;

		// Studentcode
		final Label lblStudentCode = new Label("Studentcode");
		lblStudentCode.setVisible(false);
		final TextBox txtStudentCode = new TextBox();
		txtStudentCode.setVisible(false);
		flxTable.setWidget(row, 0, lblStudentCode);
		flxTable.setWidget(row, 1, txtStudentCode);
		row++;

		// Klascode
		final Label lblKlascode = new Label("Klascode");
		lblKlascode.setVisible(false);

		lstKlascode = new ListBox();
		lstKlascode.setVisible(false);
		lstKlascode.addItem("Kies een klas");

		// Opleiding
		final Label lblOpleiding = new Label("Opleiding");
		lblOpleiding.setVisible(false);

		lstOpleiding = new ListBox();
		lstOpleiding.setVisible(false);
		lstOpleiding.addItem("Kies een opleiding");
		lstOpleiding.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent e) {
				if (lstKlascode.getItemCount() == 1) {
					List<String> klassen = fri.getKlassen(lstFaculteit.getValue(lstFaculteit.getSelectedIndex()), lstOpleiding.getValue(lstOpleiding.getSelectedIndex()));
					if (klassen != null && !klassen.isEmpty()) {
						for (String klas : klassen) {
							lstKlascode.addItem(fri.getKlasNaam(klas), klas);
						}
						lblKlascode.setVisible(true);
						lstKlascode.setVisible(true);
					}
				}
			}
		});

		// Faculteit
		final Label lblFaculteit = new Label("Faculteit");
		lblFaculteit.setVisible(false);

		lstFaculteit = new ListBox();
		lstFaculteit.setVisible(false);
		lstFaculteit.addItem("Kies een faculteit");
		for (String faculteit : fri.getFaculteiten()) {
			lstFaculteit.addItem(fri.getFaculteitNaam(faculteit), faculteit);
		}
		lstFaculteit.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent e) {
				if (lstOpleiding.getItemCount() == 1) {
					List<String> opleidingen = fri.getOpleidingen(lstFaculteit.getValue(lstFaculteit.getSelectedIndex()));
					if (opleidingen != null && !opleidingen.isEmpty()) {
						for (String opleiding : opleidingen) {
							lstOpleiding.addItem(fri.getOpleidingsNaam(opleiding), opleiding);
						}
						lblOpleiding.setVisible(true);
						lstOpleiding.setVisible(true);
					}
				}
			}
		});

		// Faculteit op het panel plaatsen
		flxTable.setWidget(row, 0, lblFaculteit);
		flxTable.setWidget(row, 1, lstFaculteit);
		row++;

		// Opleiding op het panel plaatsen
		flxTable.setWidget(row, 0, lblOpleiding);
		flxTable.setWidget(row, 1, lstOpleiding);
		row++;

		// Klascode op het panel plaatsen
		flxTable.setWidget(row, 0, lblKlascode);
		flxTable.setWidget(row, 1, lstKlascode);
		row++;

		// Docentcode
		final Label lblDocentCode = new Label("Docentcode");
		lblDocentCode.setVisible(false);
		final TextBox txtDocentCode = new TextBox();
		txtDocentCode.setVisible(false);
		flxTable.setWidget(row, 0, lblDocentCode);
		flxTable.setWidget(row, 1, txtDocentCode);
		row++;

		// Klascode
		final Label lblKlasCode = new Label("Klascode");
		lblKlasCode.setVisible(false);
		final TextBox txtKlasCode = new TextBox();
		txtKlasCode.setVisible(false);
		flxTable.setWidget(row, 0, lblKlasCode);
		flxTable.setWidget(row, 1, txtKlasCode);
		row++;

		// Type Student
		final RadioButton rbStudent = new RadioButton("type", "Student");
		rbStudent.setFormValue(Gebruiker.TYPE_STUDENT.toString());
		rbStudent.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (rbStudent.getValue()) {
					// Studentcode tonen
					lblStudentCode.setVisible(rbStudent.getValue());
					txtStudentCode.setVisible(rbStudent.getValue());

					// Faculteit tonen
					lblFaculteit.setVisible(rbStudent.getValue());
					lstFaculteit.setVisible(rbStudent.getValue());

					if (lblDocentCode.isVisible()) {
						lblDocentCode.setVisible(false);
						txtDocentCode.setVisible(false);
					}
				}
			}
		});
		flxTable.setWidget(row, 0, rbStudent);
		row++;

		// Type Docent
		final RadioButton rbDocent = new RadioButton("type", "Docent");
		rbDocent.setFormValue(Gebruiker.TYPE_DOCENT.toString());
		rbDocent.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				// Docentcode tonen
				lblDocentCode.setVisible(rbDocent.getValue());
				txtDocentCode.setVisible(rbDocent.getValue());

				if (lblStudentCode.isVisible()) {
					// Studentcode verbergen
					lblStudentCode.setVisible(false);
					txtStudentCode.setVisible(false);

					// Faculteit verbergen
					lblFaculteit.setVisible(false);
					lstFaculteit.setVisible(false);

					// Opleiding verbergen
					lblOpleiding.setVisible(false);
					lstOpleiding.setVisible(false);

					// Klascode verbergen
					lblKlasCode.setVisible(false);
					lstKlascode.setVisible(false);
				}
			}
		});
		flxTable.setWidget(row, 0, rbDocent);
		row++;

		// Type TeamLeider Personeelszaken
		final RadioButton rbTeamLeider = new RadioButton("type", "TeamLeider Personeelszaken");
		rbTeamLeider.setFormValue(Gebruiker.TYPE_TEAMLEIDER.toString());
		rbTeamLeider.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				// Docent checken, eventueel verbergen
				if (lblDocentCode.isVisible()) {
					lblDocentCode.setVisible(false);
					txtDocentCode.setVisible(false);
				}

				// Student velden checken eventueel verbergen
				if (lblStudentCode.isVisible()) {
					lblStudentCode.setVisible(false);
					txtStudentCode.setVisible(false);

					lblKlasCode.setVisible(false);
					txtKlasCode.setVisible(false);

					lblFaculteit.setVisible(false);
					lstFaculteit.setVisible(false);

					lblOpleiding.setVisible(false);
					lstOpleiding.setVisible(false);

					lblKlascode.setVisible(false);
					lstKlascode.setVisible(false);
				}
			}
		});
		flxTable.setWidget(row, 0, rbTeamLeider);
		row++;
		
		// Type TeamLeider Personeelszaken
		final RadioButton rbManagerBedrijfsvoering = new RadioButton("type", "Manager Bedrijfsvoering");
		rbManagerBedrijfsvoering.setFormValue(Gebruiker.TYPE_MANAGER_BEDRIJFSVOERING.toString());
		rbManagerBedrijfsvoering.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				// Docent checken, eventueel verbergen
				if (lblDocentCode.isVisible()) {
					lblDocentCode.setVisible(false);
					txtDocentCode.setVisible(false);
				}

				// Student velden checken eventueel verbergen
				if (lblStudentCode.isVisible()) {
					lblStudentCode.setVisible(false);
					txtStudentCode.setVisible(false);

					lblKlasCode.setVisible(false);
					txtKlasCode.setVisible(false);

					lblFaculteit.setVisible(false);
					lstFaculteit.setVisible(false);

					lblOpleiding.setVisible(false);
					lstOpleiding.setVisible(false);

					lblKlascode.setVisible(false);
					lstKlascode.setVisible(false);
				}
			}
		});
		flxTable.setWidget(row, 0, rbManagerBedrijfsvoering);
		row++;

		// Is Administrator (Default true)
		Label lblIsAdministrator = new Label("Administrator");
		CheckBox chkIsAdministrator = new CheckBox();
		chkIsAdministrator.setFormValue("1");
		chkIsAdministrator.setValue(true);
		chkIsAdministrator.setEnabled(false);
		flxTable.setWidget(row, 0, lblIsAdministrator);
		flxTable.setWidget(row, 1, chkIsAdministrator);
		row++;

		// Submit button
		Image imgSubmit = new Image();
		imgSubmit.setAltText("Account aanmaken");
		imgSubmit.setUrl("style/icon/tick.png");

		// Submitbutton + event.
		Button btnSubmit = new Button();
		btnSubmit.setHTML("Account aanmaken " + imgSubmit.toString());
		btnSubmit.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {

				String email = txtEmail.getValue();
				String voornaam = txtVoornaam.getValue();
				String achternaam = txtAchternaam.getValue();

				final Gebruiker gebruiker = new Gebruiker();
				gebruiker.setEmail(email);
				gebruiker.setVoornaam(voornaam);
				gebruiker.setAchternaam(achternaam);
				gebruiker.setIsAdministrator(true);

				// Student
				if (rbStudent.getValue()) {

					gebruiker.setType(Gebruiker.TYPE_STUDENT);
					gebruiker.setStudentNummer(txtStudentCode.getValue());
					gebruiker.setFaculteit(lstFaculteit.getValue(lstFaculteit.getSelectedIndex()));
					gebruiker.setOpleiding(lstOpleiding.getValue(lstOpleiding.getSelectedIndex()));
					gebruiker.setKlasCode(lstKlascode.getValue(lstKlascode.getSelectedIndex()));

					if (gebruiker.getKlasCode().equals("")) {
						Window.alert("Faculteit, opleiding en klascode mogen niet leeg zijn.");
						return;
					}

					if (gebruiker.getStudentNummer().equals("")) {
						Window.alert("Studentnummer is leeg.");
						return;
					}
				// Docent
				} else if (rbDocent.getValue()) {

					gebruiker.setType(Gebruiker.TYPE_DOCENT);
					gebruiker.setDocentCode(txtDocentCode.getValue());

					if (gebruiker.getDocentCode().equals("")) {
						Window.alert("Docentcode is leeg.");
						return;
					}
				// Teamleider
				} else {
					gebruiker.setType(Gebruiker.TYPE_TEAMLEIDER);
				}

				if (!gebruiker.getEmail().equals("")) {
					if (!gebruiker.getAchternaam().equals("") || gebruiker.getVoornaam().equals("")) {
						service.addGebruiker(gebruiker, new AsyncCallback<Gebruiker>() {
							public void onFailure(Throwable caught) {
								Window.alert("Er ging iets fout tijdens het opslaan van de gegevens. Probeer het later nog een keer.");
								log.info("Service failure -> addGebruiker(" + gebruiker.toString() + ") -> " + caught.getMessage());
							}

							@Override
							public void onSuccess(Gebruiker G) {
								Window.alert("Gebruiker " + G.getEmail() + " kan nu inloggen.");

								// Menu
								MenuFactory mf = new MenuFactory();
								mf.refreshMenuBar();

								new Dashboard();
							}
						});
					} else {
						Window.alert("Voor- en/of achternaam zijn leeg.");
					}
				} else {
					Window.alert("Email adres is niet ingevult.");
				}
			}
		});
		flxTable.setWidget(row, 0, btnSubmit);

		// Header table
		RootPanel.get("content").add(flxTableHeader);

		// Data table
		RootPanel.get("content").add(flxTable);

		Abcensys.setLoadingImage(false);
	}
}
